前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

在上一小节,我带你实现了一个简单的 JavaScript AST 解析器,你也应该对词法分析和语法分析底层原理有了一定的了解。那么在本小节的内容中,我们将基于 AST 解析器来实现一个模块打包工具(Bundler),也就是实现一个精简版的 Rollup。通过本节的实战学习,你不仅能对各种 AST 的各种操作信手拈来,还能够对 JavaScript 模块打包工具本身有更加深刻的理解。

# 实现思路梳理

首先我们来梳理一下整体的实现思路,如下图所示:

第一步我们需要获取模块的内容并解析模块 AST,然后梳理模块间的依赖关系,生成一张模块依赖图(ModuleGraph)。

接下来,我们根据模块依赖图生成拓扑排序后的模块列表,以保证最后的产物中各个模块的顺序是正确的,比如模块 A 依赖了模块 B,那么在产物中,模块 B 的代码需要保证在模块 A 的代码之前执行。

当然,Tree Shaking 的实现也是很重要的一环,我会带你实现一个基于 import/export 符号分析的 Tree Shaking 效果,保证只有被 import 的部分被打包进产物。最后,我们便可以输出完整的 Bundle 代码,完成模块打包。

# 开发环境搭建

我们先来搭建一下项目的基本开发环境,首先新建目录my-bundler,然后进入目录中执行 pnpm init -y 初始化,安装一些必要的依赖:

pnpm i magic-string -S
pnpm i @types/node tsup typescript typescript-transform-paths -D
@前端进阶之旅: 代码已经复制到剪贴板

新建tsconfig.json,内容如下:

{
  "compilerOptions": {
    "target": "es2016",
    "allowJs": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "baseUrl": "src",
    "rootDir": "src",
    "declaration": true,
    "plugins": [
      {
        "transform": "typescript-transform-paths"/* 支持别名 */
      },
      {
        "transform": "typescript-transform-paths",
        "afterDeclarations": true/* 支持类型文件中的别名 */
      }
    ],
    "paths": {
      "*": ["./*"],
      "ast-parser": ["../../ast-parser"]/* AST 解析器的路径*/
    }
  },
  "include": ["src"],
  "references": [{ "path": "../ast-parser" }]
}
@前端进阶之旅:
fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏